/*****************************************************************************
*   adc.c:  source file for adc module
*		ver 1.0
******************************************************************************/

#include "me32g030.h"
#include "me32g030_sys.h"
#include "me32g030_adc.h"

extern uint32_t MainCoreClock;

/*****************************************************************************
Function Name	ADC_Init
Function Definition	void ADC_Init(uint32_t conversionrate,,uint8_t vrefsel)
Function Description	Initial ADC module
Input Parameters	Conversionrate: conversion rate, must less 1000000 (1MHz)
									vrefsel:INTERNALVDDGND/EXTVREFPGND/INTERNALADCVREFGND
Return Value	No
Condition	No
Function called	-

*****************************************************************************/
void ADC_Init(uint32_t conversionrate,uint8_t vrefsel)
{
	uint32_t temp,div;

	//Power up ADC
	SYSCON->PDRUNCFG_b.ADC_PD = 0;
	if (vrefsel==INTERNALADCVREFGND)
	{
		SYSCON->VREFSEL = 0; //cutout ext vrefp
		SYSCON->PDRUNCFG_b.VREF_PD = 0; //power on adc vref
	}else
		SYSCON->VREFSEL = 1; //connect ext vrefp
	//enable clock of ADC digital
	SYSCON->SYSAHBCLKCTRL_b.ADC_CLK = 1;

	//reset ADC digital
	SYSCON->PRESETCTRL_b.ADC_RST_N = 0;
	SYSCON->PRESETCTRL_b.ADC_RST_N = 1;
	
	ADC->CR_b.RST_ALL=1;
	//insert a delay
	temp=0xff;
	while (temp--);
	ADC->CR_b.RST_ALL=0;

	//limit convertion rate to 1M/s
	if (conversionrate>1000000)
		conversionrate = 1000000;
	conversionrate=conversionrate<<4;
	
	//caculate clk divider
	div = MainClock/conversionrate;

	if (((div*conversionrate)!=MainClock)&&(MainClock>16000000*div))
		div++;
	
	//set up divider
	SYSCON->ADCCLKDIV = div;
	
	//LSEN must be 1
	ADC->CR_b.LSEN=1;
	
	//ADC VREF select
	ADC->CR_b.ADCVREF=vrefsel;
	
	//Enable calibration 
	ADC->CALCR_b.CAL_EN=1;
	while((ADC->STAT&0x20)==0x00); //wait for cal start
	while((ADC->STAT&0x24)!=0x04); //make sure both EOC done and BUSY free, wait for cal end
	
	return;
}
/*****************************************************************************
Function Name	ADC_DeInit
Function Definition	Void ADC_DeInit(viod)
Function Description	De_Initial ADC module. Disable interrupt generated by module and stop any conversion.
Input Parameters	No
Return Value	No
Condition	No
Function called	-

*****************************************************************************/
void ADC_DeInit(void)
{
	
	ADC->INTEN=0;
	//Power down ADC
	SYSCON->PDRUNCFG_b.ADC_PD = 1;
	SYSCON->PDRUNCFG_b.VREF_PD = 1;
	//disable clock of ADC digital
	SYSCON->SYSAHBCLKCTRL_b.ADC_CLK = 0;

	return;
}
/*****************************************************************************
Function Name	ADC_SetupChannels
Function Definition	Void ADC_SetupChannels (uint32_t channelassign, uint32_t triggermode)
Function Description	Select AD channels to be converted and AD conversion trigger mode
Input Parameters		channelassign: AD channel and DR assignment. Ref CHSEL register description. 
										Example AD0|AD1, channel AD0 conversion value will be in DR0, and channel AD1 conversion value will be in DR1
										triggermode;	BURSTMODE/TRIGGERMODE
Return Value	No
Condition	No
Function called	-

*****************************************************************************/
void ADC_SetupChannels (uint32_t channelassign, uint32_t triggermode)
{

	//setup ad channels conversion enable
			
	ADC->CHNEN = channelassign;								

	//Select burst mode or triggermode
	ADC->CR_b.BURST = triggermode;
	return;
}
/*****************************************************************************
Function Name	ADC_SetTrigger
Function Definition	Void ADC_SetTrigger(uint8_t triggersrc, uint8_t edge)
Function Description	Setup trigger source signal if ADC is in trigger mode
Input Parameters	Triggersrc: select one option
										ADC_START_BY_SOFTWAER, 
										ADC_START_BY_TIM1_CAP0, 
										ADC_START_BY_TIM1_CAP1, 
										ADC_START_BY_TIM1_MAT0,
										ADC_START_BY_TIM1_MAT1,
										ADC_START_BY_TIM0_MAT,
										ADC_START_BY_PWM
Return Value	No
Condition	No
Function called	-

*****************************************************************************/
void ADC_SetTrigger(uint8_t triggersrc, uint8_t edge)
{
	//set up ADC start mode 
	ADC->CR_b.START = triggersrc;
	ADC->CR_b.EDGE	= edge;
	return;
}
/*****************************************************************************
Function Name	void ADC_Calibation
Function Definition	void ADC_Calibation(void)
Function Description	ADC Calibration
Input Parameters	none
Return Value	No
Condition	No
Function called	-

*****************************************************************************/
void ADC_Calibation(void)
{
	ADC->CALCR_b.EOCAL_CLR = 1;
	ADC->CALCR_b.CAL_EN = 1;
	while(ADC->STAT_b.BUSY != 1);
	while(ADC->STAT_b.BUSY);
	
	return;
}

/*****************************************************************************
Function Name	ADC_EnableConversionInt
Function Definition	Void ADC_EnableConversionInt(uint32_t inttype)
Function Description	Setup conversion completed interrupt
Input Parameters		inttype: combination of interrupt source-
										bit 0~7 related to ADC channel0~ 7 value updated
										bit 8 related ADC global register updated
Return Value	No
Condition	No
Function called	-

*****************************************************************************/
void ADC_EnableConversionInt(uint32_t inttype)
{
	ADC->INTEN =  inttype;
	
	return;
}

/******************************************************************************
**                            End Of File
******************************************************************************/
